package com.moose.operator.socket.io;

import com.corundumstudio.socketio.AuthorizationListener;
import com.corundumstudio.socketio.HandshakeData;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * <p>
 * Description:
 * </p>
 *
 * @author taohua
 * @version v1.0.0
 * @date 2021-01-23 08:37:08:37
 * @see com.moose.operator.configure
 */
@Slf4j
@Configuration
public class SocketIoConfiguration {

  @Resource
  @Lazy
  private TokenStore tokenStore;

  /**
   * netty-socketio服务器
   */
  @Bean
  public SocketIOServer socketIOServer() {
    com.corundumstudio.socketio.Configuration config =
        new com.corundumstudio.socketio.Configuration();
    // 设置访问 host 地址
    config.setHostname("localhost");

    // 设置端口
    config.setPort(9000);

    // 设置是否可以跨域访问
    config.setOrigin("*");

    // 鉴权管理 --> SpringBoot OAuth2.0 封装登录、刷新令牌接口
    config.setAuthorizationListener(new AuthorizationListener() {
      @Override public boolean isAuthorized(HandshakeData data) {
        String accessToken = data.getSingleUrlParam(OAuth2AccessToken.ACCESS_TOKEN);
        if (StringUtils.isEmpty(accessToken)) {
          return false;
        }
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(accessToken);
        return !ObjectUtils.isEmpty(oAuth2AccessToken);
      }
    });
    return new SocketIOServer(config);
  }

  /**
   * 用于扫描 netty-socketio 注解 比如 @OnConnect、@OnEvent
   */
  @Bean
  public SpringAnnotationScanner springAnnotationScanner() {
    return new SpringAnnotationScanner(socketIOServer());
  }
}
